<?
// CLASSE rint2Date - per la gestione delle date
if (!class_exists('rint2Date')) {
class rint2Date {
   // le propriet� della classe sono modificate solo dal costruttore e dai metodi set...
   // nei metodi :
   //    $mvDate = mixed variable contenete la data nel formato definito da tipo
   //    $tipo = formato di $mvDate - puo essere
   //       dmy  : gg/mm/aa[aa] gg-mm-aa[aa] ggmmaa gmmaa gmaa ggmmaaaa  (default)
   //       ymd  : aa[aa]/mm/gg aa[aa]-mm-gg aammgg aammg aamg aaaammgg
   //       unix  : unix time stamp
   //       object : oggetto classe 'rint2Date'
   public $day;
   public $month;
   public $year;
   public $centuryBase=60;
   
   public function __construct($mvDate='', $type='dmy') {
      if ($mvDate == '') {
         $mvDate=time();
         $type='uni';
      }
      $this->set($mvDate,$type);
   }

   function set($mvDate, $type='dmy') {
      switch (substr(strtolower($type),0,3)) {
         case 'dmy':
            return $this->setDMY($mvDate);
         case 'ymd':
            return $this->setYMD($mvDate);
         case 'obj':
            return $this->setObject($mvDate);
         case 'uni' :
         default :
            return $this->setUnix($mvDate);
      }
   }

   function setUnix($mvDate) {
      if (!is_numeric($mvDate)) return false;
      $this->year  = intval(date('Y',$mvDate));
      $this->month = intval(date('m',$mvDate));
      $this->day   = intval(date('d',$mvDate));
      return true;
   }

   function setObject($mvDate) {
      if (get_class($mvDate) != 'rint2Date') return false;
      $this->year  = $mvDate->year;
      $this->month = $mvDate->month;
      $this->day   = $mvDate->day;
      return true;
   }

   function setDMY($mvDate) {
      $mvDate = trim(strval($mvDate));
      $aD = preg_split("/[\/-]/",$mvDate);
      if (count($aD) == 3) {
         list($dd, $mm, $yy) = $aD;
      }
      if (count($aD) == 1) {
         if (!preg_match("/[0-9]/",$mvDate)) { return false; }
         switch (strlen($mvDate)) {
         case 4: $dd = substr($mvDate,0,1); $mm = substr($mvDate,1,1); $yy = substr($mvDate,2,2);
            break;
         case 5: $dd = substr($mvDate,0,1); $mm = substr($mvDate,1,2); $yy = substr($mvDate,3,2);
            break;
         case 6: $dd = substr($mvDate,0,2); $mm = substr($mvDate,2,2); $yy = substr($mvDate,4,2);
            break;
         case 7: $dd = substr($mvDate,0,1); $mm = substr($mvDate,1,2); $yy = substr($mvDate,3,4);
            break;
         case 8: $dd = substr($mvDate,0,2); $mm = substr($mvDate,2,2); $yy = substr($mvDate,4,4);
            break;
         default:
            return false;
         }
      }
      $yy = trim($yy); $mm = trim($mm); $dd = trim($dd);
      if (empty($yy) or empty($mm) or empty($dd)) return false;
      if (!preg_match("/[0-9]/",$yy.$mm.$dd)) return false;
      if (strlen($yy) == 2) {
         if ($yy == 0) $yy = "2000";
         if ($yy < 100) {
              if ($yy <= $this->centuryBase) { $yy = strval(intval($yy) + 2000); }
              else { $yy = strval(intval($yy) + 1900); }
         }
      }
      if (strlen($yy) != 4) {
      	return false;
      }
      if (is_numeric($mm) && is_numeric($dd) && is_numeric($yy) && checkdate($mm, $dd, $yy)) {
         $this->year  = intval($yy);
         $this->month = intval($mm);
         $this->day   = intval($dd);
         return true;
      }
      return false;
   }

   function setYMD($mvDate) {
      $mvDate = trim(strval($mvDate));
      $aD = preg_split("/[\/-]/",$mvDate);
      if (count($aD) == 3) {
         list($yy, $mm, $dd) = $aD;
      }
      if (count($aD) == 1) {
         if (!preg_match("/[0-9]/",$mvDate)) { return false; }
         switch (strlen($mvDate)) {
         case 4: $dd = substr($mvDate,3,1); $mm = substr($mvDate,2,1); $yy = substr($mvDate,0,2);
            break;
         case 5: $dd = substr($mvDate,4,1); $mm = substr($mvDate,2,2); $yy = substr($mvDate,0,2);
            break;
         case 6: $dd = substr($mvDate,4,2); $mm = substr($mvDate,2,2); $yy = substr($mvDate,0,2);
            break;
         case 7: $dd = substr($mvDate,6,1); $mm = substr($mvDate,4,2); $yy = substr($mvDate,0,4);
            break;
         case 8: $dd = substr($mvDate,6,2); $mm = substr($mvDate,4,2); $yy = substr($mvDate,0,4);
            break;
         default:
            return false;
         }
      }
      $yy = trim($yy); $mm = trim($mm); $dd = trim($dd);
      if (empty($yy) or empty($mm) or empty($dd)) return false;
      if (!preg_match("/[0-9]/",$yy.$mm.$dd)) return false;
      if ($yy > 9999) { return false; }
      if (strlen($yy) == 2) {
         if ($yy == 0) $yy = "2000";
         if ($yy < 100) {
              if ($yy <= $this->centuryBase) { $yy = strval(intval($yy) + 2000); }
              else { $yy = strval(intval($yy) + 1900); }
         }
      }
      if (strlen($yy) != 4) {
      	return false;
      }
      if (checkdate(intval($mm), intval($dd), intval($yy))) {
         $this->year  = intval($yy);
         $this->month = intval($mm);
         $this->day   = intval($dd);
         return true;
      }
      return false;
   }

   function setDayAdd($num, $typeOut='dmy', $mvDate='', $type='dmy') {
      if ($mvDate != '') { if(!$this->set($mvDate,$type)) return false; }
      $this->day += intval($num);
      $aGdm = array(0,31,28,31,30,31,30,31,31,30,31,30,31);
      if ($this->isLeap()) { $aGdm[2] = 29; }
      while($this->day < 1) {
         $this->month--;
         if ($this->month < 1) {
            $this->month = 12;
            $this->year--;
            if ($this->isLeap()) { $aGdm[2] = 29; } else { $aGdm[2] = 28; }
         }
         $this->day += $aGdm[$this->month];
      }
      while($this->day > $aGdm[$this->month]) {
         $this->day -= $aGdm[$this->month];
         $this->month++;
         if ($this->month > 12) {
            $this->month = 1;
            $this->year++;
            if ($this->isLeap()) $aGdm[2] = 29; else $aGdm[2] = 28; 
         }
      }
      return $this->get($typeOut);
   }

   function setMonthAdd($num,$typeOut='dmy', $mvDate='', $type='dmy') {
      if ($mvDate != '') { if(!$this->set($mvDate,$type)) return false; }
      $day = $this->day;
      $this->month += intval($num);
      if ($this->month > 12) {
         $this->year += intval(floor($this->month / 12));
         $this->month = intval($this->month%12);
      } elseif ($this->month < 1) {
         $this->year += intval(floor($this->month / 12) - 1);
         $this->month = intval(($this->month%12)+12);
      }
      $aGdm = array(0,31,28,31,30,31,30,31,31,30,31,30,31);
      if ($this->isLeap()) { $aGdm[2] = 29; }
      if ($this->day > $aGdm[$this->month]) { $this->day = $aGdm[$this->month]; }
      return $this->get($typeOut);
   }

   function setYearAdd($num,$typeOut='dmy', $mvDate='', $type='dmy') {
      if ($mvDate != '') { if(!$this->set($mvDate,$type)) return false; }
      $day = $this->day;
      $this->year += intval($num);
      if ($this->day == 29 and $this->month == 2 and !$this->isLeap()) {
         $this->day = 28;
      }
      return $this->get($typeOut);
   }

   function get($typeOut='dmy', $mvDate='', $type='dmy') {
      switch (strtolower($typeOut)) {
         case 'dmy' :
         case 'dmy/4' :
            return $this->getDMY('/', 4, $mvDate='', $type);
            break;
         case 'dmy-4' :
            return $this->getDMY('-', 4, $mvDate='', $type);
            break;
         case 'dmy/2' :
            return $this->getDMY('/', 2, $mvDate='', $type);
            break;
         case 'dmy-2' :
            return $this->getDMY('-', 2, $mvDate='', $type);
            break;
         case 'ymd' :
         case 'ymd-4' :
            return $this->getYMD('-', 4, $mvDate='', $type);
            break;
         case 'ymd/4' :
            return $this->getYMD('/', 4, $mvDate='', $type);
            break;
         case 'ymd-2' :
            return $this->getYMD('-', 2, $mvDate='', $type);
            break;
         case 'ymd/2' :
            return $this->getYMD('/', 2, $mvDate='', $type);
            break;
         case 'it-long' :
            return $this->weekDay('it-long')." ".$this->day." ".$this->month('it-long')." ".$this->year;
            break;
         case 'obj':
         case 'object' :
            return $this->getObject($mvDate='', $type);
            break;
         case 'uni' :
         case 'unix' :
         default :
            return $this->getUnix($mvDate='', $type);
            break;
      }
   }

   function getDMY($sep='/', $y=4, $mvDate='', $type='dmy') {
      $odx = $this->getObject($mvDate, $type);
      if ($odx === false) return false;
      if ($y == 2) {
         return $odx->day().$sep.$odx->month().$sep.$odx->year('2');
      }
      return $odx->day().$sep.$odx->month().$sep.$odx->year('4');;
   }

   function getYMD($sep='-',$y=4, $mvDate='', $type='dmy') {
      $odx = $this->getObject($mvDate, $type);
      if ($odx === false) return false;
      if ($y == 2) {
         return $odx->year('2').$sep.$odx->month().$sep.$odx->day();
      }
      return $odx->year('4').$sep.$odx->month().$sep.$odx->day();
   }

   function getUnix($mvDate='', $type='dmy') {
      $odx = clone $this->getObject($mvDate, $type);
      if ($odx === false) return false;
      return mktime(0,0,0,$odx->month,$odx->day,$odx->year);
   }

   function getObject($mvDate='', $type='dmy') {
      if ($mvDate != '') {
         $odx = new rint2Date();
         if (!$odx->set($mvDate, $type)) {
            return false;
         }
      } else {
         $odx = clone $this;
      }
      return $odx;
   }

   function getDayAdd($num, $typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone $this->getObject($mvDate, $type);
      return $odx->setDayAdd($num, $typeOut);
   }

   function getMonthAdd($num, $typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      return $odx->setMonthAdd($num, $typeOut);
   }

   function getYearAdd($num, $typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      return $odx->setYearAdd($num, $typeOut);
   }

   function DMY2YMD($mvDate, $sep='-', $y=4) {
      return $this->getYMD($sep,$y,$mvDate,'dmy');
   }

   function YMD2DMY($mvDate, $sep='/', $y=4) {
      return $this->getDMY($sep,$y,$mvDate,'ymd');
   }

   function isHoliday($holidays="default", $mvDate='',$type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      if ($holidays == "default" or $holidays=='') {
         $holidays = "01/01,06/01,25/04,01/05,02/06,15/08,01/11,08/12,25/12,26/12";
      }
      if ($odx->weekDay() == 0 or $odx->weekDay() == 6) {
         return true;
      }
      $ddmm = str_pad($odx->day,2,'0',STR_PAD_LEFT).'/'.str_pad($odx->month,2,'0',STR_PAD_LEFT);
      if (strpos($holidays, $ddmm) !== false) {
         return true;
      }
      if (function_exists('easter_date') and $odx->year >= 1970 and $odx->year <= 2037) {
         $easter_monday = date('d/m/Y',easter_date($odx->year) + 36*3600);
         if ($easter_monday == $odx->get('dmy')) {
            return true;
         }
      }
      return false;
   }

   function prevNoHoliday($typeOut='dmy', $holidays="default", $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $odx->setDayAdd(-1);
      while ($odx->isHoliday($holidays)) {
         $odx->setDayAdd(-1);
      }
      return $odx->get($typeOut);
   }

   function nextNoHoliday($typeOut='dmy', $holidays="default", $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $odx->setDayAdd(+1);
      while ($odx->isHoliday($holidays)) {
         $odx->setDayAdd(+1);
      }
      return $odx->get($typeOut);
   }

   function dayCount($mvDate='',$type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $aGdm = array(0,31,28,31,30,31,30,31,31,30,31,30,31);
      if ($odx->isLeap()) { $aGdm[2] = 29; }
      $dc = ($odx->year - 1) * 365 + floor(($odx->year-1)/4)
         - floor(($odx->year-1)/100) + floor(($odx->year-1)/400);
      for($k=1; $k<$odx->month; $k++) {
         $dc += $aGdm[$k];
      }
      $dc += $odx->day;
      return $dc;
   }

   function dayDiff($mvDate2, $type2, $mvDate1='', $type1='dmy') {
      $odx1 = $this->getObject($mvDate1, $type1);
      if ($odx1 === false) { return false; }
      $odx2 = $this->getObject($mvDate2, $type2);
      if ($odx2 === false) { return false; }
      return ($odx2->dayCount() - $odx1->dayCount());
   }

   function compare($mvDate1, $type1, $mvDate2='', $type2='dmy') {
      $odx1 = $this->getObject($mvDate1, $type1);
      if ($odx1 === false) { return false; }
      $odx2 = $this->getObject($mvDate2, $type2);
      if ($odx2 === false) { return false; }
      if ($odx1->getYMD() < $odx2->getYMD()) {
         return -1;
      } elseif ($odx1->getYMD() > $odx2->getYMD()) {
         return +1;
      }
      return 0;
   }

   function weekFirst($typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $dow = $odx->weekDay('index');
      if ($dow == 0) {$from_mon = -6;}
      else {$from_mon = 1 - $dow; }
      return $odx->getDayAdd($from_mon, $typeOut);
   }

   function weekLast($typeOut='dmy',  $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $dow = $odx->weekDay('index');
      if ($dow == 0) {$to_sun = 0;}
      else {$to_sun = 7 - $dow;}
      return $odx->getDayAdd($to_sun, $typeOut);
   }

   function monthFirst($typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $odx->day = 1;
      return $odx->get($typeOut);
   }

   function monthLast($typeOut='dmy',  $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $odx->setMonthAdd(1);
      $odx->day = 1;
      $odx->setDayAdd(-1);
      return $odx->get($typeOut);
   }

   function quarterFirst($typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $odx->day = 1;
      if ($odx->month > 9) {
         $odx->month = 10;
      } elseif ($odx->month > 6) {
         $odx->month = 7;
      } elseif ($odx->month > 3) {
         $odx->month = 4;
      } else {
         $odx->month = 1;
      }
      return $odx->get($typeOut);
   }

   function quarterLast($typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      if ($odx->month > 9) {
         $odx->day = 31;
         $odx->month = 12;
      } elseif ($odx->month > 6) {
         $odx->day = 30;
         $odx->month = 9;
      } elseif ($odx->month > 3) {
         $odx->day = 30;
         $odx->month = 6;
      } else {
         $odx->day = 31;
         $odx->month = 3;
      }
      return $odx->get($typeOut);
   }

   function halfYearFirst($typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $odx->day = 1;
      if ($odx->month > 6) {
         $odx->month = 7;
      } else {
         $odx->month = 1;
      }
      return $odx->get($typeOut);
   }

   function halfYearLast($typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      if ($odx->month > 6) {
         $odx->day = 31;
         $odx->month = 12;
      } else {
         $odx->day = 30;
         $odx->month = 6;
      }
      return $odx->get($typeOut);
   }

   function yearFirst($typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $odx->day = 1;
      $odx->month = 1;
      return $odx->get($typeOut);
   }

   function yearLast($typeOut='dmy', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $odx->day = 31;
      $odx->month = 12;
      return $odx->get($typeOut);
   }

   function day($typeOut='str', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      if ($typeOut == 'num') {
         return (integer)$odx->day;
      }
      return str_pad($this->day,2,'0',STR_PAD_LEFT);
   }

   function month($typeOut='str', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $typeOut = strtolower($typeOut);
      if ($typeOut == 'num') {
         return (integer)$odx->month;
      }
      if ($typeOut == 'it-short') {
         $aMoy = array('','gen','feb','mar','apr','mag','giu','lug','ago','set','ott','nov','dic');
         return $aMoy[(int)$odx->month];
      }
      if ($typeOut == 'it-long') {
         $aMoy = array('','gennaio','febbraio','marzo','aprile','maggio','giugno','luglio',
            'agosto','settembre','ottobre','novembre','dicembre');
         return $aMoy[(int)$odx->month];
      }
      return str_pad($this->month,2,'0',STR_PAD_LEFT);
   }

   function year($typeOut='str', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $typeOut = strtolower($typeOut);
      if ($typeOut == 'num') {
         return (integer)$odx->year;
      }
      if ($typeOut == '2') {
         return substr(strval($odx->year),-2);
      }
      return strval($odx->year);
   }

   function weekDay($typeOut='index', $mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      $weekDay = ($odx->dayCount())%7;
      $typeOut = strtolower($typeOut);
      if ($typeOut == 'index') {
         return $weekDay;
      }
      if ($typeOut == 'it-short') {
         $aWeekDay = array('dom','lun','mar','mer','gio','ven','sab');
         return isset($aWeekDay[(int)$weekDay])?$aWeekDay[(int)$weekDay]:$weekDay;
      }
      if ($typeOut == 'it-long') {
         $aWeekDay = array('domenica','lunedi\'','martedi\'','mercoledi\'','giovedi\'','venerdi\'','sabato');
         return isset($aWeekDay[(int)$weekDay])?$aWeekDay[(int)$weekDay]:$weekDay;
      }
      return $weekDay;
   }

   function isLeap($mvDate='', $type='dmy') {
      $odx = clone($this->getObject($mvDate, $type));
      if ($odx === false) { return false; }
      return (($odx->year%4 == 0 and $odx->year%100 != 0) or $odx->year%400 == 0);
   }

}
} //fine if (!class_exists('rint2Date'))
?>
